package org.grow.leave.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * @Author: xwg
 * @CreateDate: 2021/11/1
 */

@Service
public class LeaveAccessDecisionManager implements AccessDecisionManager {
    @Value("${allowed.anonymousUser:false}")
    private Boolean enableAnonymous;

    @Override
    public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> collection) throws AccessDeniedException, InsufficientAuthenticationException {
//        优先解决开发过程中匿名用户问题
//        上线时候要关闭允许匿名登陆 开发过程中建议开启允许匿名登陆
        if (enableAnonymous) {
            String name = authentication.getName();
            if (name.toLowerCase().contains("anonymous")) {
                return;
            }
        }
//
        Collection<? extends GrantedAuthority> rolesFromUser = authentication.getAuthorities();
        Collection<ConfigAttribute> rolesFromUrl = collection;
        System.out.println("从用户-角色表联查出的角色集合 " + rolesFromUser);
        System.out.println("从权限-角色表联查出的角色集合 " + rolesFromUrl);
//        取交集
        Boolean r = false;
        for (GrantedAuthority authority : rolesFromUser) {
            String a = authority.getAuthority();
            for (ConfigAttribute configAttribute : rolesFromUrl) {
                String b = configAttribute.getAttribute();
                if (a.equals(b)) {
                    r = true;
                    break;
                }
            }
        }
        if (!r) {
            System.out.println("权限验证角色无交集，发生权限拦截");
            FilterInvocation filterInvocation = (FilterInvocation) o;
            String requestUrl = filterInvocation.getRequestUrl();
            String reason = "权限拦截： " + authentication.getName() + "因为角色问题不足以访问 " + requestUrl;
            throw new AccessDeniedException(reason);
        }


    }

    @Override
    public boolean supports(ConfigAttribute configAttribute) {
        return false;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return false;
    }
}
